package com.disktalk.service;

import com.disktalk.api.Config;
import com.disktalk.api.FastDFS;
import com.disktalk.dao.DiskFileDao;
import com.disktalk.entry.DiskFile;
import com.disktalk.entry.PageBean;
import com.disktalk.util.StringUtil;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import java.io.File;
import java.util.*;

@Service
public class DiskFileService {

    @Resource
    private DiskFileDao diskFileDao;
    @Resource
    private DiskFile diskFile;

    //private static List<DiskFile> diskFileList;

    private static Object[] params;

    /**
     * 添加文件信息到数据库
     *
     * @param diskFile
     * @return
     */
    public boolean addFileMsg(DiskFile diskFile) {
        try {
            diskFileDao.addDiskFile(diskFile);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 获得总数
     *
     * @param fileFlag
     * @param userName
     * @return
     */
    public Integer getCount(String fileFlag, String userName) {
        Object[] params = new Object[]{fileFlag, userName};
        StringBuffer hql = new StringBuffer("select count(*) from diskFile where fileFlag = ? and uploadUser = ? ");
        return diskFileDao.getFileCountByUserName(hql.toString(), params);
    }

    /**
     * 删除数据库中文件信息
     *
     * @param uuid
     * @return
     */
    public boolean delDiskFile(String uuid) {
        String sql = "delete from diskFile where UUID=?";
        Object[] params = {uuid};
        try {
            diskFileDao.delDiskFile(sql, params);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }
    }

    /**
     * 查询用户文件
     *
     * @param userName
     * @return
     */
    public List<DiskFile> findDiskFileList(String userName, String uuid, PageBean pageBean, String fileFlag) {
        StringBuffer hql = new StringBuffer("select * from diskFile where fileFlag = ? ");
        List<String> list = new ArrayList<>();
        list.add(fileFlag);
        if (StringUtil.isNotEmpty(userName)) {
            hql.append(" and uploadUser like \"%\"?\"%\"");
            list.add(userName);
        }
        if (StringUtil.isNotEmpty(uuid)) {
            hql.append(" and uuid like \"%\"?\"%\"");
            list.add(uuid);
        }
        params = getParams(list);
        hql.append(" order by uploadDate desc ");
        hql.append("limit " + pageBean.getStart() + "," + pageBean.getPageSize());
        System.out.println("=======findDiskFileList========" + hql.toString());
        return diskFileDao.findDiskFileList(hql.toString(), params);
    }

    /**
     * 根据文件名查询
     *
     * @param userName
     * @param fileName
     * @return
     */
    public List<DiskFile> searchFile(String userName, String fileName, PageBean pageBean, String fileFlag) {
        StringBuffer hql = new StringBuffer("select * from diskFile and fileFlag = ?");
        List<String> list = new ArrayList<>();
        list.add(fileFlag);
        if (StringUtil.isNotEmpty(fileName)) {
            hql.append(" and fileName like \"%\"?\"%\"");
            list.add(fileName);
        }
        if (StringUtil.isNotEmpty(userName)) {
            hql.append(" and uploadUser like \"%\"?\"%\"");
            list.add(userName);
        }
        hql.append(" order by uploadDate desc ");
        hql.append("limit " + pageBean.getStart() + "," + pageBean.getPageSize());
        Object[] params = getParams(list);
        return diskFileDao.searchFile(hql.toString().replaceFirst("and", "where"), params);
    }

    /**
     * 获得文件个数
     *
     * @param userName 上传用户
     * @param fileName 文件名称
     * @return
     */
    public Integer getCountByuNameOrfName(String userName, String fileName, String type) {
        StringBuffer hql = new StringBuffer("select count(*) from diskFile ");
        List<String> list = new ArrayList<>();
        list = new ArrayList<>();
        if (StringUtil.isNotEmpty(userName)) {
            hql.append(" and userName like \"%\"?\"%\"");
            list.add(userName);
        }
        if (StringUtil.isNotEmpty(fileName)) {
            hql.append(" and fileName like \"%\"?\"%\"");
            list.add(fileName);
        }
        if (StringUtil.isNotEmpty(type)) {
            hql.append(" and fileFlag = ?");
            list.add(type);
        }
        params = getParams(list);
        System.out.println("==========" + hql.toString().replaceFirst("and", "where"));
        return diskFileDao.getFileCountByUserName(hql.toString().replaceFirst("and", "where"), params);
    }


    public Integer getCount(String fileFlag) {
        StringBuffer hql = new StringBuffer("select count(*) from diskFile where fileFlag = ?");
        Object[] params = new Object[]{fileFlag};
        return diskFileDao.getFileCountByUserName(hql.toString(), params);
    }

    /**
     * 获得参数
     *
     * @param arrayList
     * @return
     */
    private static Object[] getParams(List<String> arrayList) {
        Object[] param = new Object[arrayList.size()];
        for (int i = 0; i < arrayList.size(); i++) {
            param[i] = arrayList.get(i);
        }
        return param;
    }

    /**
     * 根据uuid查询文件
     *
     * @param uuid
     * @return
     */
    public DiskFile findDiskFile(String uuid) {
        StringBuffer hql = new StringBuffer("select * from diskFile where uuid = ?");
        Object[] params = new Object[]{uuid};
        hql.append(" ORDER BY uploadDate desc");
        return diskFileDao.getDiskFile(hql.toString(), params);
    }

    /**
     * 修改文件信息
     *
     * @param diskFile
     * @return
     */
    public void updateFile(DiskFile diskFile) {
        try {
            diskFileDao.updateFile(diskFile);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 分享文件
     *
     * @param diskFile
     * @param downloadPwd
     * @return
     */
    public boolean share(DiskFile diskFile, String downloadPwd) {
        UUID uuid = UUID.randomUUID();
        diskFile.setUuid(uuid.toString());
        diskFile.setFileName(diskFile.getFileName());
        diskFile.setFileSize(diskFile.getFileSize());
        diskFile.setFileExt(diskFile.getFileExt());
        diskFile.setFileUrl(diskFile.getFileUrl());
        diskFile.setDfsGroupName(diskFile.getDfsGroupName());
        diskFile.setUploadUser(diskFile.getUploadUser());
        diskFile.setIspublic("1");// 1表示分享文件，0表示自身文件
        diskFile.setFileFlag("2");//0表示存放在最新文件，1表示存放在回收站,2表示分享文件
        diskFile.setDownloadPwd(downloadPwd);
        diskFile.setDfsGroupName(diskFile.getDfsGroupName());
        return addFileMsg(diskFile);
    }

    /**
     * 文件下载
     *
     * @param groupName      组名，比如"group1"
     * @param remoteFileName 文件名，比如"M00/00/3F/wKgrMlkdx7-AJIZgAAA-5vvGciE98902_big.c"
     * @param //saveTo       下载到硬盘的文件名
     */
    public static ResponseEntity<byte[]> download(String groupName, String remoteFileName, String specFileName) {
        byte[] content = null;

        System.out.println("==groupName===" + groupName + " ====remoteFileName==" + remoteFileName
                + " ====specFileName====" + specFileName);

        HttpHeaders headers = new HttpHeaders();
        try {
            content = FastDFS.Download(groupName, remoteFileName);
            headers.setContentDispositionFormData("attachment",
                    new String(specFileName.getBytes("UTF-8"), "iso-8859-1"));
            headers.setContentType(MediaType.APPLICATION_OCTET_STREAM);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return new ResponseEntity<byte[]>(content, headers, HttpStatus.CREATED);
    }

    /**
     * 上传文件
     *
     * @param request
     * @return
     * @throws Exception
     */
    public boolean uploadFile(HttpServletRequest request) throws Exception {
        boolean isMultipart;
        int maxFileSize = 1000000 * 1024;
        int maxMemSize = 4 * 1024;
        String[] msgs;
        isMultipart = ServletFileUpload.isMultipartContent(request);
        request.setCharacterEncoding("utf-8");
        System.out.println("是否多文件：" + isMultipart);
        DiskFileItemFactory factory = new DiskFileItemFactory();
        // 内存缓存最大值
        factory.setSizeThreshold(maxMemSize);
        // 内存缓存最大值超出时本地存储路径
        factory.setRepository(new File(Config.CACHEREPOSITORY));
        // Create a new file upload handler
        ServletFileUpload upload = new ServletFileUpload(factory);
        // 设置最大上传文件大小
        upload.setSizeMax(maxFileSize);
        try {
            // 处理Request请求
            System.out.println("处理Request请求");
            List<FileItem> fileItems = upload.parseRequest(request);
            System.out.println(1);
            // 处理多个文件上传
            Iterator<FileItem> i = fileItems.iterator();
            System.out.println(2);
            while (i.hasNext()) {
                System.out.println(3);
                FileItem fi = i.next();
                System.out.println(4);
                if (!fi.isFormField()) {
                    String fileName = fi.getName();
                    System.out.println("写入fdfs");
                    // 写入fdfs开始时间
                    Date begin = new Date();
                    // 同步方式上传
                    try {
                        msgs = upload(fi, fileName);
                    } catch (java.lang.NullPointerException ex) {
                        msgs = upload(fi, fileName);
                    } catch (java.lang.IllegalArgumentException ex) {
                        msgs = upload(fi, fileName);
                    }
                    // 写入fdfs结束时间
                    Date end = new Date();
                    long between = end.getTime() - begin.getTime();
                    System.out.println("uploadTime===" + between);
                    UUID uuid = UUID.randomUUID();
                    diskFile.setUuid(uuid.toString());
                    diskFile.setFileName(fileName.lastIndexOf("\\") == -1 ? fileName
                            : fileName.substring(fileName.lastIndexOf("\\") + 1));
                    diskFile.setFileSize(fi.getSize());
                    diskFile.setFileExt(
                            fileName.lastIndexOf(".") == -1 ? "" : fileName.substring(fileName.lastIndexOf(".") + 1));
                    diskFile.setFileUrl(msgs[1]);
                    diskFile.setDfsGroupName(msgs[0]);
                    diskFile.setUploadUser((String) request.getSession().getAttribute("userName"));
                    diskFile.setIspublic("0");
                    diskFile.setFileFlag("0");//0表示存放在最新文件，1表示存放在回收站
                    diskFile.setGroupName("");
                    diskFile.setDownloadPwd("");
                    // 文件信息存入数据库
                    addFileMsg(diskFile);
                    return true;

                }
            }
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return false;
    }

    /**
     * 把文件放在回收中
     *
     * @param uuid
     * @param fileFlag
     * @return boolean fileFlag: 1-放在回收 0-是默认值
     */
    public boolean updateFileRestore(String uuid, String fileFlag) {
        String sql = "update diskFile set fileFlag = ?  where uuid = ?";
        Object[] params = {fileFlag, uuid};
        try {
            diskFileDao.updateFileFlag(sql, params);
            return true;
        } catch (Exception e) {
            e.printStackTrace();
            return false;
        }

    }

    /**
     * 彻底删除文件(清空回收站)
     *
     * @param groupName      组名，比如"group1"
     * @param remoteFileName 文件名，比如"M00/00/3F/wKgrMlkdx7-AJIZgAAA-5vvGciE98902_big.c"
     * @return
     */
    public boolean Delete(String groupName, String remoteFileName, String uuid) {
        int i = FastDFS.Delete(groupName, remoteFileName);
        if (i == 0) {
            return delDiskFile(uuid);
        }
        return false;
    }

    public String[] upload(FileItem fi, String fileName) {
        String[] resultArr;
        resultArr = FastDFS.Upload(fi.get(), null,
                fileName.lastIndexOf(".") == -1 ? "" : fileName.substring(fileName.lastIndexOf(".") + 1));
        System.out.println(resultArr[0]);
        System.out.println(resultArr[1]);
        return resultArr;
    }
}
